package com.imooc.springboot.dubbo.nilinili.provider.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.imooc.springboot.dubbo.nilinili.entity.dto.PhotoDTO;
import com.imooc.springboot.dubbo.nilinili.entity.bean.PageBean;
import com.imooc.springboot.dubbo.nilinili.entity.dto.PhotoDetailDTO;
import com.imooc.springboot.dubbo.nilinili.provider.entity.po.PhotoPO;
import com.imooc.springboot.dubbo.nilinili.provider.mapper.*;
import com.imooc.springboot.dubbo.nilinili.provider.utils.BeanCopierUtil;
import com.imooc.springboot.dubbo.nilinili.provider.utils.JwtToUserId;
import com.imooc.springboot.dubbo.nilinili.provider.utils.RedisCache;
import com.imooc.springboot.dubbo.nilinili.res.CodeEnum;
import com.imooc.springboot.dubbo.nilinili.res.ResultFactory;
import com.imooc.springboot.dubbo.nilinili.service.PhotoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service(interfaceClass = PhotoService.class)
public class PhotoServiceImpl implements PhotoService {

    @Autowired
    private PhotoMapper photoMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private ShufflingMapper shufflingMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    RedisCache redisCache;

    @Override
    public PageBean<PhotoDTO> selectPhotoPagesByCategoryId(Integer pageNum, Integer pageSize, Integer id) {
        PageHelper.startPage(pageNum,pageSize);
        List<PhotoPO> photoPOS = photoMapper.selectPhotoPagesByCategoryId(id);
        PageBean<PhotoPO> photoPOPageBean = new PageBean<>(photoPOS);
        PageBean<PhotoDTO> photoDTOPageBean = BeanCopierUtil.CopyPageBean(photoPOPageBean, PhotoDTO.class);
        return photoDTOPageBean;
    }



    @Override
    public List<PhotoDTO> selectPhotosByCategoryId(Integer id) {
        List<PhotoDTO> photoDTOS = BeanCopierUtil.copyObjects(photoMapper.selectPhotoPagesByCategoryId(id),PhotoDTO.class);
        return photoDTOS;
    }

    @Override
    public List<PhotoDTO> selectAllPhotos() {
        List<PhotoDTO> photoDTOS = BeanCopierUtil.copyObjects(photoMapper.selectAllPhotos(), PhotoDTO.class);
        return photoDTOS;
    }

    @Override
    public PhotoDetailDTO getPhotoById(Integer id) {
        PhotoDetailDTO photoDetailDTO = BeanCopierUtil.copyProperties(photoMapper.selectPhotoById(id), PhotoDetailDTO.class);
        return photoDetailDTO;
    }

    @Override
    public String getShuffingUrls() {
        return ResultFactory.createResult(CodeEnum.SUCCESS,"查询成功", shufflingMapper.getShufflingList());
    }

    @Override
    @Transactional
    public String updateApprovalCounts(Integer photoId,String token) {
        //  进入redis查询是否已经点赞过
        // 解析token
        String userId = JwtToUserId.Jwt2UserId(token);
        // 查询redis
        String key = userId+":"+photoId;
        //可能会出现redis中存入后，并发请求导致查redis时还未存入
        synchronized (this){
            // 查询是否已经点赞过
            //  如果点赞过，返回错误信息
            if (redisCache.getCacheObject(key) != null){
                return ResultFactory.createResult(CodeEnum.FAIL,"已经点赞过了");
            }
            // 如果没有点赞过，更新数据库
            Integer rows = photoMapper.updateApprovalCountsById(photoId);
            if(rows > 0){
                Integer approvalCounts = photoMapper.selectApprovalCountsById(photoId);
                redisCache.setCacheObject(key,"1",1, TimeUnit.DAYS);
                return ResultFactory.createResult(CodeEnum.SUCCESS, "点赞成功", approvalCounts);
            }
        }
        return ResultFactory.createResult(CodeEnum.FAIL, "点赞失败");
    }


    @Override
    public String getPhotosByUserId(String userId, int pageNum) {
        if ( pageNum <= 0){
            pageNum =1;
        }
        PageHelper.startPage(pageNum, 9);
        List<PhotoPO> photoPOS = photoMapper.selectPhotosByUserId(userId);
        PageBean<PhotoPO> photoPOPageBean = new PageBean<>(photoPOS);
        PageBean<PhotoDTO> photoDTOPageBean = BeanCopierUtil.CopyPageBean(photoPOPageBean, PhotoDTO.class);
        return ResultFactory.createResult(CodeEnum.SUCCESS, "查询成功", photoDTOPageBean);
    }

    @Override
    public boolean insertPhoto(PhotoDetailDTO photoDetailDTO, String token) {
        // 解析token
        String userId = JwtToUserId.Jwt2UserId(token);
        photoDetailDTO.setUserId(userId);
        PhotoPO photoPO = BeanCopierUtil.copyProperties(photoDetailDTO, PhotoPO.class);
        Integer integer = photoMapper.insertPhoto(photoPO);
        if (integer > 0){
            return true;
        }
        return false;
    }

    @Override
    public List<PhotoDTO> getNewPhoto() {
        List<PhotoDTO> photoDTOS = BeanCopierUtil.copyObjects(photoMapper.getNewPhoto(), PhotoDTO.class);
        return photoDTOS;
    }

    @Override
    public void getAllPhotoApprovalCounts(String userId) {
        synchronized (this){
            int count = 0;
            List<PhotoPO> photoPOS = photoMapper.selectPhotosByUserId(userId);
            for (PhotoPO photoPO : photoPOS) {
                count += Integer.parseInt(photoPO.getApprovalCounts());
            }
            // 将数量写入数据库
            userMapper.setNewPhotoApprovalCounts(userId, String.valueOf(count));
        }
    }

    @Override
    public void getAllPhotoCounts(String userId) {
        synchronized (this) {
            userMapper.setNewPhotoCount(userId, String.valueOf(photoMapper.selectPhotosByUserId(userId).size()));
        }
    }

    @Override
    @Transactional
    public String deletePhotoByPhotoId(String photoId){
        int i = photoMapper.deletePhoto(photoId);
        if (i > 0){
            // 同时删除所在图片下的评论
            commentMapper.deleteComment(photoId);
            return ResultFactory.createResult(CodeEnum.SUCCESS, "删除成功");
        }
        return ResultFactory.createResult(CodeEnum.FAIL, "删除失败");
    }

    @Override
    public List<PhotoDTO> getPhotoByName(String photoName) {
        List<PhotoPO> photoByName = photoMapper.getPhotoByName(photoName);
        if (photoByName.size() > 0){
            return BeanCopierUtil.copyObjects(photoByName, PhotoDTO.class);
        }
        else {
            return null;
        }
    }

    @Override
    public boolean addPhotoViewCount(Integer photoId) {
        Integer integer = photoMapper.addPhotoViewCount(photoId);
        if (integer > 0){
            return true;
        }
        return false;
    }
}
